import { View, Text, Image } from '@tarojs/components'
import Taro, { createSelectorQuery } from '@tarojs/taro'
import React, { useRef, useState, useMemo, useCallback, useEffect } from 'react'
import { DynamicColors } from '@/utils/DarkMode'
import { SliderGProps } from './slider-g'

import { getRect, rpxToPx, uuid } from './utils'

import './index.less'

interface IPointProps {
  left: number
  maxWidth: number
}
const POINT_WIDTH = rpxToPx(27)
const BOX_PADDING = rpxToPx(10)
const Point = ({ left, maxWidth }: IPointProps) => {
  let newLeft = left + BOX_PADDING
  newLeft -= POINT_WIDTH
  if (newLeft < 0) {
    newLeft = BOX_PADDING - 2
  }
  const newMaxWidth = maxWidth - POINT_WIDTH * 2
  if (newLeft > newMaxWidth + BOX_PADDING) {
    newLeft = newMaxWidth + BOX_PADDING
  }
  return <View style={{ left: newLeft, backgroundColor: DynamicColors.tintColor.value }} className='slider-point centerFlex'>
    <View className='handle' />
  </View>
}

export function SliderG({
  value,
  max,
  min,
  showValue = false,
  placeholder = false,
  radiusType = 'round',
  indicator = 'point',
  onChange,
  step,
  id,
  formatter,
  disabled,
}: SliderGProps) {
  const [boxWidth, setBoxWidth] = useState(0)
  const [valueState, setValue] = useState(value)
  const domRef = useRef<any>(null)
  const propsId = useRef<string>(id || uuid())
  const touchState = useRef(false)
  const positionRef = useRef({
    left: 0,
    width: 0,
  })

  const onCompleteHandle = useCallback(
    (data) => {
      console.log('onCompleteHandle', data)
      onChange && onChange(data)
      // Taro.vibrateShort()
    },
    [onChange],
  )

  useEffect(() => {
    Taro.nextTick(() => {
      getRect(null, `#${propsId.current}`).then((rect: any) => {
        positionRef.current = {
          left: rect.left,
          width: rect.width,
        }
      })
    })
  }, [])

  useEffect(() => {
    if (touchState.current) return
    if (value !== valueState) {
      setValue(value)
    }
  }, [value, valueState])

  useEffect(() => {
    Taro.nextTick(() => {
      const other = createSelectorQuery().select(`#${propsId.current}`)
      other
        .boundingClientRect((rect) => {
          if (rect && rect.width) {
            setBoxWidth(rect.width)
          }
        })
        .exec()
    })
  }, [])

  const width = useMemo(() => {
    const w = ((valueState - min) / (max - min)) * 100 ?? 0
    return isNaN(w) ? 0 : w
  }, [valueState, min, max])

  const onAdd = useCallback(() => {
    if (disabled) {
      return;
    }
    let valueData = step + valueState
    if (valueData > max) {
      valueData = max
    }
    setValue(valueData)
    onCompleteHandle(valueData)
  }, [valueState, step, disabled, max, onCompleteHandle])

  const onMinus = useCallback(() => {
    if (disabled) {
      return;
    }
    let valueData = valueState - step
    // 0 作为占位
    if (valueData < min) {
      return
    }
    if (valueData < min) {
      valueData = min
    }
    setValue(valueData)
    onCompleteHandle(valueData)
  }, [valueState, step, setValue, onCompleteHandle, min, disabled])

  const getValue = useCallback(
    (ratio) => {
      if (step) {
        return Math.max(
          min,
          Math.min(max, min + Math.round((ratio * (max - min)) / step) * step),
        )
      }
      return Math.max(min, Math.min(max, ratio * (max - min) + min))
    },
    [step, min, max],
  )

  const onTouchChange = useCallback(
    (e) => {
      const offsetX = e.touches[0].pageX - positionRef.current.left
      const newValue = getValue(offsetX / positionRef.current.width)
      // 0 作为占位
      if (newValue < min) {
        return
      }
      setValue(newValue)
    },
    [getValue, setValue, min],
  )

  const onTouchStart = useCallback(
    (e) => {
      if (disabled) {
        return;
      }
      // console.log('eee', e)
      if (
        e.mpEvent.target.id !== propsId.current &&
        e.mpEvent.target.id !== `${propsId.current}-inner`
      ) {
        return
      }
      touchState.current = true
      onTouchChange(e)
    },
    [onTouchChange, disabled],
  )
  const onTouchMove = useCallback(
    (e) => {
      if (!touchState.current) {
        return
      }
      onTouchChange(e)
    },
    [onTouchChange],
  )
  const onTouchEnd = useCallback(
    (e) => {
      touchState.current = false
      onCompleteHandle(valueState)
    },
    [onCompleteHandle, valueState],
  )

  const showTips = width > 20 && width <= 100
  const placeholderLength = useMemo(() => {
    return parseInt(`${(max - min) / step}`, 10)
  }, [min, max, step])

  return (
    <View className={`slider-wapper ${radiusType}`}>
      {indicator == 'point' && (
        <Point maxWidth={boxWidth} left={(width / 100) * boxWidth}></Point>
      )}
      {placeholder && (
        <View className='slider-placeholder'>
          {new Array(placeholderLength).fill(0).map((_, index) => {
            return <View key={index} className={`placeholder ${index == placeholderLength - 1 ? 'disabled' : ''}`} />
          })}
        </View>
      )}

      <View
        ref={domRef}
        onTouchStart={onTouchStart}
        onTouchMove={onTouchMove}
        onTouchEnd={onTouchEnd}
        id={propsId.current}
        className='slider-container'
      >
        {indicator == 'button' && (
          <>
            <Text onClick={onMinus} className='slider-minus'>
              -
            </Text>
            <Text onClick={onAdd} className='slider-add'>
              +
            </Text>
          </>
        )}

        <View
          id={`${propsId.current}-inner`}
          className={`slider-inner ${indicator === 'point' ? 'point' : ''}`}
          style={{ width: `${width}%`, backgroundColor: DynamicColors.tintColor.value }}
        >
          {indicator == 'button' && (
            <Text onClick={onMinus} className='slider-minus'>
              -
            </Text>
          )}

          {/* <Text onClick={onAdd} className="slider-add" style={{left: boxWidth - 70 / 2}}>+</Text> */}
          {/* point 模式下，固定显示在左边 */}
          {showValue && showTips && (
            <Text className='slider-value'>
              {formatter ? formatter(valueState) : valueState}
            </Text>
          )}
        </View>
      </View>
    </View>
  )
}

export default SliderG
